#include "StdAfx.h"

void Orders::FireOrderStatusChangedEvent(int orderIndex, OrderData ^orderData, bool firstTimeThatGotQuantity)
{
	this->OrderStatusChanged(orderIndex, orderData, firstTimeThatGotQuantity);
}

int Orders::NewOrder(int quantity, Side side, OrderTypes orderType, float stopPrice, float limitPrice, bool multiplyBySubAccounts)
{
	stopPrice = RoundNum(stopPrice);
	limitPrice = RoundNum(limitPrice);

	TWSLib::IContract ^ic = owner->Account_()->TwsControl()->createContract();
	TWSLib::IOrder ^ord = owner->Account_()->TwsControl()->createOrder();

	ic->symbol = owner->Name();
	ic->secType = "STK";
	ic->currency = "USD";
	ic->exchange = "SMART";

	ord->totalQuantity = quantity;
	if (side == Long) ord->action = "BUY";
	if (side == Short) ord->action = "SELL";
	if (orderType == Market) ord->orderType = "MKT";
	if (orderType == Limit) ord->orderType = "LMT";
	if (orderType == StopLimit) ord->orderType = "STPLMT";
	ord->auxPrice = RoundNum(stopPrice);
	ord->lmtPrice = RoundNum(limitPrice);
	//if (GlobalVars::UseAdvisor_IB == true)
	//{
	//	ord->faGroup = GlobalVars::Allocation;
	//	ord->faMethod = "EqualQuantity";
	//	if (orderData_IB->MultiplyBySubAccounts == true) ord->totalQuantity *= GlobalVars::SubAccounts;
	//}

	int orderID = owner->Account_()->GetNextFreeOrderID();
	OrderData ^newOrder = gcnew OrderData(this, orders->Count, orderID, quantity, side, orderType, stopPrice, limitPrice);
	orders->Add(newOrder);
	owner->Account_()->TwsControl()->placeOrderEx(orderID, ic, ord);
	return orders->Count - 1;
}

void Orders::UpdateOrder(int orderIndex, int quantity, Side side, OrderTypes orderType, float stopPrice, float limitPrice, bool multiplyBySubAccounts)
{
	stopPrice = RoundNum(stopPrice);
	limitPrice = RoundNum(limitPrice);

	TWSLib::IContract ^ic = owner->Account_()->TwsControl()->createContract();
	TWSLib::IOrder ^ord = owner->Account_()->TwsControl()->createOrder();

	ic->symbol = owner->Name();
	ic->secType = "STK";
	ic->currency = "USD";
	ic->exchange = "SMART";

	ord->totalQuantity = quantity;
	if (side == Long) ord->action = "BUY";
	if (side == Short) ord->action = "SELL";
	if (orderType == Market) ord->orderType = "MKT";
	if (orderType == Limit) ord->orderType = "LMT";
	if (orderType == StopLimit) ord->orderType = "STPLMT";
	ord->auxPrice = RoundNum(stopPrice);
	ord->lmtPrice = RoundNum(limitPrice);
	//if (GlobalVars::UseAdvisor_IB == true)
	//{
	//	ord->faGroup = GlobalVars::Allocation;
	//	ord->faMethod = "EqualQuantity";
	//	if (orderData_IB->MultiplyBySubAccounts == true) ord->totalQuantity *= GlobalVars::SubAccounts;
	//}

	owner->Account_()->TwsControl()->placeOrderEx(((OrderData^)orders[orderIndex])->OrderID(), ic, ord);
}

void Orders::CancelLimitsAndSellQuantity()
{
	int i, filled;

	for (i=0; i<orders->Count; i++)
		orders[i]->CancelLimit();
	Application::DoEvents();
	filled = AllFilledQuantity();
	if (filled == 0) return;
	NewOrder(Math::Abs(filled), (filled > 0 ? Short : Long), Market, 0, 0, false);
}

void Orders::CancelLimitsAndSellQuantity(float limitPrice)
{
	int i, filled;

	for (i=0; i<orders->Count; i++)
		orders[i]->CancelLimit();
	Application::DoEvents();
	filled = AllFilledQuantity();
	if (filled == 0) return;
	NewOrder(Math::Abs(filled), (filled > 0 ? Short : Long), Limit, 0, limitPrice, false);
}

int Orders::AllFilledQuantity()
{
	int i, counter = 0;

	for (i=0; i<orders->Count; i++)
		counter += orders[i]->FilledQuantity();

	return counter;
}

OrderData^ Orders::operator[](int index)
{
	return orders[index];
}

Orders::Orders(Symbol ^owner)
{
	this->owner = owner;
	orders = gcnew List<OrderData^>;
}

// ****************************************************************************************************

void OrderData::CancelLimit()
{
	owner->Owner()->Account_()->TwsControl()->cancelOrder(orderID);
}

OrderData::OrderData(Orders ^owner, int orderIndex, int orderID, int totalQuantity, Side side, OrderTypes orderType, float stopPrice, float limitPrice)
{
	this->owner = owner;
	owner->Owner()->Account_()->TwsControl()->orderStatus += gcnew AxTWSLib::_DTwsEvents_orderStatusEventHandler(this, &OrderData::getOrderStatus);
	this->orderID = orderID;
	this->orderIndex = orderIndex;
	this->filledQuantity = 0;
	this->remainingQuantity = totalQuantity;
	this->totalQuantity = totalQuantity;
	this->side = side;
	this->orderType = orderType;
	this->stopPrice = stopPrice;
	this->limitPrice = limitPrice;
	this->status = "";
}

void OrderData::getOrderStatus(System::Object ^sender, AxTWSLib::_DTwsEvents_orderStatusEvent ^e)
{
	if (e->id == orderID)
	{
		bool firstTimeThatGotQuantity = false;

		if (this->filledQuantity == 0 && e->filled != 0) firstTimeThatGotQuantity = true;
		this->filledQuantity = e->filled;
		this->remainingQuantity = e->remaining;
		this->status = e->status;
		owner->FireOrderStatusChangedEvent(orderIndex, this, firstTimeThatGotQuantity);
	}
}